package com.producer.config;

import feign.Response;
import feign.Util;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.HttpMessageConverterCustomizer;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import com.utils.json.JacksonUtil;

import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.Objects;

import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * @author Liunh
 */
public class FeignClientDecoder extends SpringDecoder {

    public FeignClientDecoder(ObjectFactory<HttpMessageConverters> messageConverters, ObjectProvider<HttpMessageConverterCustomizer> customizers) {
        super(messageConverters, customizers);
    }

    @Override
    public Object decode(Response response, Type type) throws IOException {
        final Response.Body body = response.body();
        final String bodyClassName = body.getClass().getName();
        //Response.ByteArrayBody feign.Response$InputStreamBody feign.Response$ByteArrayBody
        //因为ByteArrayBody是private 所以不能instance of
        if (Objects.equals(bodyClassName, "feign.Response$ByteArrayBody") || Objects.equals(bodyClassName, "feign.Response$InputStreamBody")) {
            String result;
            if (Objects.equals(bodyClassName, "feign.Response$ByteArrayBody")) {
                result = body.toString();
            } else {
                byte[] bodyData = Util.toByteArray(body.asInputStream());
                result = Util.decodeOrDefault(bodyData, UTF_8, "Binary data");
            }
            final Response.Builder respBuild = Response.builder()
                    .headers(response.headers())
                    .reason(response.reason())
                    .status(response.status())
                    .request(response.request());
            if (StringUtils.isNoneBlank(result)) {
                respBuild.body(JacksonUtil.beanToJson(result), Charset.defaultCharset());
            } else {
                respBuild.body(result, Charset.defaultCharset());
            }
            return super.decode(respBuild.build(), type);
        }
        return super.decode(response, type);
    }

}
